package cn.sdormitory.sys.service.impl;

import cn.sdormitory.common.IdAndName;
import cn.sdormitory.common.utils.ContainerUtil;
import cn.sdormitory.sys.dao.SysUserRoleDao;
import cn.sdormitory.sys.entity.SysUserRole;
import cn.sdormitory.sys.service.SysRoleService;
import cn.sdormitory.sys.service.SysUserRoleService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 后台用户和角色关系表
 */
@Service("sysUserRoleService")
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleDao, SysUserRole> implements SysUserRoleService {

    @Resource
    private SysRoleService sysRoleService;

    @Override
    public List<Long> listRoleIdByUserId(Long userId) {
        List<Long> ids = new ArrayList<>();
        List<SysUserRole> sysUserRoles = this.baseMapper.selectList(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
        if (CollectionUtil.isNotEmpty(sysUserRoles)) {
            sysUserRoles.forEach(item -> {
                ids.add(item.getRoleId());
            });
            return ids;
        }
        return null;
    }

    @Override
    public void insertUserAndUserRole(Long userId, List<Long> roleIdList) {
        this.baseMapper.insertUserAndUserRole(userId, roleIdList);
    }

    @Override
    public void delAndCreateRole(Long userId, List<Long> roleIdList) {
        remove(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
        if (CollUtil.isNotEmpty(roleIdList)) {
            //保存用户与角色关系
            insertUserAndUserRole(userId, roleIdList);
        }
    }

    @Override
    public List<Integer> listDataScopesByUserId(Long userId) {
        return this.baseMapper.listDataScopesByUserId(userId);
    }

    @Override
    public Map<Long, List<IdAndName<Long>>> getUserIdAndRoleIdNamesMappings(List<Long> userIds) {
        if(CollUtil.isEmpty(userIds)){
            return Collections.emptyMap();
        }
        List<SysUserRole> sysUserRoles = list(Wrappers.<SysUserRole>lambdaQuery()
                .select(SysUserRole::getUserId,SysUserRole::getRoleId)
                .in(SysUserRole::getUserId, userIds));
        Set<Long> roleIds = ContainerUtil.mapSet(sysUserRoles, SysUserRole::getRoleId);
        if(ContainerUtil.isEmpty(roleIds)){
            return Collections.emptyMap();
        }
        List<IdAndName<Long>> roleIdAndNames = sysRoleService.listIdAndName(roleIds);
        Map<Long, String> roleIdAndNameMapping = ContainerUtil.toMapSafe(roleIdAndNames, IdAndName::getId, IdAndName::getName);
        if(ContainerUtil.isEmpty(roleIdAndNameMapping)){
            return Collections.emptyMap();
        }

        Map<Long, List<SysUserRole>> userRolesGroupByUserId = ContainerUtil.groupBySafe(sysUserRoles, SysUserRole::getUserId);
        return ContainerUtil.mapValue(userRolesGroupByUserId,
                roles -> ContainerUtil.map(roles, role -> IdAndName.generate(role.getRoleId(), roleIdAndNameMapping.get(role.getRoleId())))
                        .filter(item->item != null && item.getId() != null && item.getName() != null)
                        .collect(Collectors.toList()),
                true);
    }

}
